
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <assert.h>

#include <windows.h>
#include <Winsock.h>

#include "ThreadPool.h"
#include "PoolJob.h"
#include "Communicator.h"
#include "Engine.h"


static BOOL	__stdcall ctrlHandler(DWORD ctrlEvent);

int main(int argc, char *argv[])
{
	int		numberOfThread = 0;
	int		proxyPort = 0;
	int		proxyMode = 0;
	int		ret;


	if( argc != 4 ) {
		fprintf(stderr, "Usage:%s <proxy mode> <port> <maximum number of threads>\n\n", argv[0]);
		exit(1);
	}

	numberOfThread = (int)strtol(argv[3], (char **)NULL, 10);
	proxyPort = (int)strtol(argv[2], (char **)NULL, 10);
	proxyMode = (int)strtol(argv[1], (char **)NULL, 10);

	if( numberOfThread==LONG_MAX || numberOfThread==LONG_MIN ||
		proxyPort==LONG_MAX || proxyPort==LONG_MIN ||
		proxyMode==LONG_MAX || proxyMode==LONG_MIN) {
		fprintf(stderr, "Usage:%s <port> <maximum number of threads>\n\n", argv[0]);
		exit(1);
	}

	// Register a console control handler
	if( !SetConsoleCtrlHandler(ctrlHandler, TRUE))
		fprintf(stderr, "Error setting event handler\n");

	// create and initialize a proxy engine
	CProxyEngine &engine = CProxyEngine::GetInstance();
	PROXY_INFO pi;
	pi.mode = (unsigned int)proxyMode;
	pi.maxPool = (unsigned int)numberOfThread;
	pi.proxyPort = (short)proxyPort;
	engine.InitProxyEngine(pi);

	const HANDLE *engineThread;
	DWORD dw;

	ret = engine.proxyStart();
	if(ret == 1) {
		engineThread = engine.getEngineThread();
		dw = WaitForSingleObject(*engineThread, INFINITE);
		if(dw == WAIT_FAILED) {
			fprintf(stderr, "The engine thread waiting failed!");
			exit(1);
		}
	}

	engine.DestroyProxyEngine();

	printf("\nProgram Exit!\n\n");

}


BOOL __stdcall ctrlHandler(DWORD ctrlEvent)
{
	switch(ctrlEvent) {
		case CTRL_C_EVENT:
		case CTRL_CLOSE_EVENT:
			printf("close event reveived\n");
			CProxyEngine::GetInstance().DestroyProxyEngine();
			Sleep(2000);
			exit(0);
		default:
			return TRUE;
	}
}